#import "RNContainerCell.h"
#import "RNConstants.h"

static NSColor *backgroundColor, *backgroundColorSelected, *backgroundColorInactive;
static NSColor *countBoxColor, *countBoxColorInactive, *countBoxColorSelected, *countBoxColorSelectedInactive;
static NSColor *countTextColor, *countTextColorInactive;
static NSColor *highlightBorderColor, *highlightFillColor;


#pragma mark -
@interface RNContainerCell (RNContainerCellPrivateMethods)
-(NSAttributedString *)itemCountAttributedString;
@end

#pragma mark -
@implementation RNContainerCell

@synthesize itemsCount = itemsCount_;
@synthesize titleAttributes = titleAttributes_;
@synthesize itemCountHover = itemCountHover_;


#pragma mark -
#pragma mark Class methods

+(void)initialize {
    backgroundColor = [NSColor colorWithCalibratedWhite:0.95 alpha:1.0];
    backgroundColorSelected = [NSColor colorWithCalibratedRed:0.851 green:0.890 blue:0.957 alpha:1.000];
    backgroundColorInactive = [NSColor colorWithCalibratedWhite:0.8 alpha:1.0];
    countBoxColor = [NSColor colorWithCalibratedRed:0.819 green:0.860 blue:0.916 alpha:1.000];
    countBoxColorInactive = [NSColor colorWithCalibratedWhite:0.85 alpha:1.0];
    countBoxColorSelected = [NSColor colorWithCalibratedRed:0.789 green:0.831 blue:0.920 alpha:1.000];
    countBoxColorSelectedInactive = [NSColor colorWithCalibratedWhite:0.75 alpha:1.0];
    highlightBorderColor = [NSColor colorWithCalibratedRed:0.0f green:0.373f blue:0.89f alpha:1.0f];
    highlightFillColor = [NSColor colorWithCalibratedRed:0.675f green:0.769f blue:0.898f alpha:0.75f];
    countTextColor = [NSColor colorWithCalibratedRed:0.496 green:0.558 blue:0.638 alpha:1.000];
    countTextColorInactive = [NSColor colorWithCalibratedWhite:0.6 alpha:1.0f];
}

+(BOOL)prefersTrackingUntilMouseUp {
    return YES;
}

+(NSFocusRingType)defaultFocusRingType {
	return NSFocusRingTypeNone;
}


#pragma mark -
#pragma mark Accessors

-(NSDictionary *)titleAttributes {
    if (!titleAttributes_) {
        NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
        [attributes setValue:[NSFont systemFontOfSize:12.0f] forKey:NSFontAttributeName];
        titleAttributes_ = (NSDictionary *)attributes;
    }
    return titleAttributes_;
}

-(id)objectValue {
	NSDictionary *objectDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[super objectValue], RNTitleKey, [self itemsCount], @"itemsCount", nil];
	NSLog(@"returning %@", objectDictionary);
	return objectDictionary;
}

-(void)setObjectValue:(id)obj {
//	NSLog(@"set object value %@", [obj class]);
//	if (!obj)
//		NSLog(@"stop");
	if ([obj isKindOfClass:[NSString class]]) {
//		NSLog(@"found string %@  representedObject is %@", obj, [self representedObject]);
		[super setObjectValue:obj];
	}
		
    if (![obj isKindOfClass:[NSDictionary class]])
        return;
    [self setItemsCount:[[obj valueForKey:@"itemsCount"] integerValue]];
    [super setObjectValue:[obj valueForKey:RNTitleKey]];
}


#pragma mark -
#pragma mark Cell Behavior

-(BOOL)isEditable {
    return YES;
}

-(BOOL)isSelectable {
    return YES;
}

- (NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    return nil;
}


#pragma mark -
#pragma mark Editing

-(NSText *)setUpFieldEditorAttributes:(NSText *)textObj {
	[textObj setDrawsBackground:NO];
	return textObj;
}

-(void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
	NSRect titleRect = [self titleFrameForCellFrame:aRect];
	[super editWithFrame:titleRect inView:controlView editor:textObj delegate:anObject event:theEvent];
}

-(void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength {
	NSRect titleRect = [self titleFrameForCellFrame:aRect];
	[super selectWithFrame:titleRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
}


#pragma mark -
#pragma mark Drawing

-(void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSRect insetFrame = NSInsetRect(cellFrame, RNDetailViewBorderPadding, 0.0f);
    NSBezierPath *boundingPath = [NSBezierPath bezierPathWithRoundedRect:insetFrame xRadius:RNDetailViewCellCornerRadius yRadius:RNDetailViewCellCornerRadius];
    
    NSRect countBoxFrame = insetFrame;
    countBoxFrame.size.width = RNCountBoxWidth;
    NSBezierPath *itemCountBoxPath = RNCountBoxPathInRect(countBoxFrame);
    
    // Draw fill
	NSResponder *firstResponder = [[controlView window] firstResponder];
	BOOL cellIsActive = [NSApp isActive] && [firstResponder isKindOfClass:[NSView class]] && [(NSView *)firstResponder isDescendantOf:controlView];
    NSColor *currentHighlightColor = cellIsActive ? backgroundColorSelected : backgroundColorInactive;
    NSColor *currentBackgroundColor = [self isHighlighted] ? currentHighlightColor : backgroundColor;
    [currentBackgroundColor setFill];
    [boundingPath fill];
    
    NSColor *currentCountBoxHighlightColor = cellIsActive ? countBoxColorSelected : countBoxColorSelectedInactive;
    NSColor *currentCountBoxColor = cellIsActive ? countBoxColor : countBoxColorInactive;
    NSColor *itemCountBoxColor = [self isHighlighted] ? currentCountBoxHighlightColor : currentCountBoxColor;
    [itemCountBoxColor setFill];
    [itemCountBoxPath fill];

    // Draw item count
    [[self itemCountAttributedString] drawInRect:[self itemCountFrameForCellFrame:cellFrame]];
    
    if ([self tag] == RNDragDropTagHighlighted) {
        [highlightBorderColor setStroke];
        [boundingPath setLineWidth:2.0f];
        [boundingPath stroke];
        [highlightFillColor setFill];
        [boundingPath fill];
    }

    // Draw Text
	[super drawWithFrame:[self titleFrameForCellFrame:cellFrame] inView:controlView];
}

- (NSAttributedString *)attributedStringValue {
    return [[NSAttributedString alloc] initWithString:[self stringValue] attributes:[self titleAttributes]];
}

-(NSAttributedString *)itemCountAttributedString {
    NSColor *textColor = [NSApp isActive] ? countTextColor : countTextColorInactive;
	NSNumber *underlineStyle = [NSNumber numberWithInteger:[self itemCountHover]];
    NSDictionary *stringAttributes = [NSDictionary dictionaryWithObjectsAndKeys:textColor, NSForegroundColorAttributeName, underlineStyle, NSUnderlineStyleAttributeName, nil];
    NSString *itemCountString = [NSString stringWithFormat:@"%i %@", [self itemsCount], ([self itemsCount] == 1 ? @"item" : @"items")];
    return [[NSAttributedString alloc] initWithString:itemCountString attributes:stringAttributes];
}

-(NSRect)titleFrameForCellFrame:(NSRect)cellFrame {
    NSSize titleSize = [[self attributedStringValue] size];
    CGFloat insetY = (NSHeight(cellFrame) - titleSize.height) / 2;
    NSRect insetFrame = NSInsetRect(cellFrame, RNDetailViewBorderPadding, insetY);
    insetFrame.origin.x += RNCountBoxWidth + RNCountBoxPadding;
	insetFrame.size.width -= (RNCountBoxWidth + RNCountBoxPadding + RNGenericCellEndPadding);
    return insetFrame;
}

-(NSRect)itemCountFrameForCellFrame:(NSRect)cellFrame {
    NSSize stringSize = [[self itemCountAttributedString] size];
    CGFloat originY = NSMidY(cellFrame) - (stringSize.height / 2);
    CGFloat originX = NSMinX(cellFrame) + RNDetailViewBorderPadding + RNCountBoxWidth - RNCountBoxPadding - stringSize.width;
    NSRect itemCountFrame = NSMakeRect(originX, originY, stringSize.width, stringSize.height);
    return itemCountFrame;
}


#pragma mark -
#pragma mark Mouse trackingArea

- (void)addTrackingAreasForView:(NSView *)view inRect:(NSRect)cellFrame withUserInfo:(NSDictionary *)userInfo mouseLocation:(NSPoint)currentPoint {
    NSRect itemCountFrame = [self itemCountFrameForCellFrame:cellFrame];
    NSTrackingAreaOptions trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp | NSTrackingEnabledDuringMouseDrag;
    NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:itemCountFrame options:trackingOptions owner:view userInfo:userInfo];
    [view addTrackingArea:trackingArea];
}

- (void)mouseEntered:(NSEvent *)event {
	[self setItemCountHover:YES];
    [(NSControl *)[self controlView] updateCell:self];
}

- (void)mouseExited:(NSEvent *)event {
	[self setItemCountHover:NO];
    [(NSControl *)[self controlView] updateCell:self];
}

- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
    NSPoint eventPoint = [controlView convertPoint:[event locationInWindow] fromView:nil];
    NSRect itemCountFrame = [self itemCountFrameForCellFrame:cellFrame];
    if ([controlView mouse:eventPoint inRect:itemCountFrame]) 
        return NSCellHitContentArea | NSCellHitTrackableArea;
	
	NSRect insetFrame = NSInsetRect(cellFrame, RNDetailViewBorderPadding, 0.0f);
    if ([controlView mouse:eventPoint inRect:insetFrame]) 
        return NSCellHitContentArea | NSCellHitEditableTextArea;
	
    return NSCellHitNone;
}

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
    NSRect itemCountFrame = [self itemCountFrameForCellFrame:cellFrame];
	while ([theEvent type] != NSLeftMouseUp) {
        NSPoint eventPoint = [controlView convertPoint:[theEvent locationInWindow] fromView:nil];
        [self setItemCountHover:[controlView mouse:eventPoint inRect:itemCountFrame]];
        if ([theEvent type] == NSMouseEntered || [theEvent type] == NSMouseExited) 
            [NSApp sendEvent:theEvent];
        theEvent = [[controlView window] nextEventMatchingMask:(NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask)];
    }
	
    if ([self itemCountHover]) {
        [NSApp sendAction:[self action] to:[self target] from:self];
        [(NSControl *)[self controlView] updateCell:self];
    }
    return YES;
}

@end
